package com.intel.factorytest.activity;

import java.io.IOException;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

import com.intel.factorytest.R;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.AudioSystem;
import android.media.AudioTrack;

public class MicrophoneSub extends BaseActivity implements
        OnClickListener, OnCompletionListener, OnErrorListener,
        MediaRecorder.OnInfoListener {
    private static final String TAG = "MicrophoneSub";
    private static final int RECORDER_MAX_DURATION = 7000;
    private static final String RECORDER_FILE_NAME = "/Recorder.3gp";
    
    private static final int MEDIA_STATE_IDLE = 0;
    private static final int MEDIA_STATE_RECORD = 1;
    private static final int MEDIA_STATE_PLAY = 2;
    
    AudioManager mAudioManager = null;

    private Button mSucBtn;
    private Button mRecordButton;
    private Button mPlayButton;
    private TextView mcTestText;

    private BroadcastReceiver mHeadsetPlug;

    private MediaRecorder mMediaRecorder;
    private MediaPlayer mMediaPlayer;

    private String sFilePath;
    
    private static int save_volume_music = 0;
    
    private static int mMediaState = MEDIA_STATE_IDLE;
    boolean mRunning = false;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e(TAG, "onCreate");
        setContentView(R.layout.microphone);

        initView();

        // String printTxtPath = getApplicationContext().getFilesDir();
        sFilePath = getApplicationContext().getFilesDir().getAbsolutePath();
        sFilePath = "/sdcard/Download";
        Log.e(TAG, "sFilePath:" + sFilePath);
        sFilePath+=RECORDER_FILE_NAME;
        Log.d(TAG, "sFilePath:" + sFilePath);

        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
//        mAudioManager.setMode(AudioManager.MODE_NORMAL);
        setAudio();
        mMediaRecorder = new MediaRecorder();
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
        mMediaRecorder.setOutputFile(sFilePath);
        mMediaRecorder.setMaxDuration(RECORDER_MAX_DURATION);
        mMediaRecorder.setOnInfoListener(this);
        
        save_volume_music = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);

        //sub mic
        mAudioManager.setParameters("MIC_CHOOSE=2");
        
        mcTestText.setText(getString(R.string.SERVICEMENU_HEADSET_MONITOR_TXT));
        
        mMediaState = MEDIA_STATE_IDLE;
    }

    protected void initView() {
        super.initView();

        mSucBtn = (Button) findViewById(R.id.success_button);
        mSucBtn.setVisibility(View.INVISIBLE);

        mRecordButton = (Button) findViewById(R.id.btn_record);
        mRecordButton.setOnClickListener(this);
        mRecordButton.setEnabled(false);
        mRecordButton.setVisibility(View.INVISIBLE);
        mPlayButton = (Button) findViewById(R.id.btn_play);
        mPlayButton.setOnClickListener(this);
        mPlayButton.setEnabled(false);
        mPlayButton.setVisibility(View.INVISIBLE);
        mcTestText = (TextView) findViewById(R.id.microphone_value);
    }

    protected synchronized void StartRecord() {
        Log.d(TAG, "StartRecord");
        if (mMediaState != MEDIA_STATE_IDLE){
            return;
        }
        mcTestText.setText(getString(R.string.SERVICEMENU_HEADSET_RECORDING_TXT));
        try {
            if (mMediaRecorder != null) {
                mMediaRecorder.prepare();
                mMediaRecorder.start();
            }
        } catch (IllegalArgumentException e) {

        } catch (IOException e) {
            e.printStackTrace();
        }
        mMediaState = MEDIA_STATE_RECORD;
    }

    protected synchronized void StopRecord() {
        Log.d(TAG, "StopRecord");
        if ((mMediaRecorder != null)&&(mMediaState == MEDIA_STATE_RECORD)) {
            mMediaRecorder.stop();
            mMediaRecorder.reset();
            mMediaRecorder.release();
        }
        mMediaState = MEDIA_STATE_IDLE;
    }

    protected synchronized void StartPlay() {
        Log.d(TAG, "StartPlay");
        if (mMediaState != MEDIA_STATE_IDLE){
            return;
        }
        mcTestText.setText(getString(R.string.SERVICEMENU_HEADSET_PLAYING_TXT));
        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mMediaPlayer.setOnCompletionListener(this);
        mMediaPlayer.setOnErrorListener(this);
        try {
            mMediaPlayer.setDataSource(sFilePath);
            if (mMediaPlayer != null) {
                mMediaPlayer.prepare();
                mMediaPlayer.start();
            }
        } catch (IllegalArgumentException e) {

        } catch (IOException e) {
            e.printStackTrace();
        }
        mMediaState = MEDIA_STATE_PLAY;
    }

    protected synchronized void StopPlay() {
        Log.d(TAG, "StopPlay");
        mcTestText.setText(getString(R.string.SERVICEMENU_HEADSET_PLAYED_TXT));
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer=null;
        }
        mMediaState = MEDIA_STATE_IDLE;
    }

    public void onClick(View v) {
        if (v.getId() == R.id.btn_record) {
            mRecordButton.setEnabled(false);
            // mRecordButton.setVisibility(View.INVISIBLE);
            // mPlayButton.setVisibility(View.VISIBLE);
            // mPlayButton.setEnabled(true);
            StopRecord();
            StartPlay();
        } else if (v.getId() == R.id.btn_play) {
            mPlayButton.setEnabled(false);

        }

    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.e(TAG, "onResume");
        //mSucBtn.setVisibility(View.VISIBLE);
        mRecordButton.setEnabled(true);
        mcTestText.setText(getString(R.string.loop_mic_test));
        // startLoopBackThread();
        StartRecord();
        mItemTestFinish = true;//add by wangsm
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.e(TAG, "onPause");
        //recoverMode();
        StopRecord();
        
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer=null;
        }
    }

    @Override
    public void finish() {
        mAudioManager.setMode(AudioManager.MODE_NORMAL);
        mRunning = false;
        setTestResult();
        super.finish();
    }

    @Override
    public void onDestroy() {
        Log.e(TAG, "onDestroy");
        //stop main mic, restore
        mAudioManager.setParameters("MIC_CHOOSE=0");
        super.onDestroy();
    }
    
    @Override
    public void onInfo(MediaRecorder mr, int what, int extra) {
        // TODO Auto-generated method stub
        switch (what) {
        case MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED:
            // automaticlly play when max duration is reached
            Log.d(TAG, "MEDIA_RECORDER_INFO_MAX_DURATION_REACHED");
            mRecordButton.setEnabled(false);
            StopRecord();
            StartPlay();
            break;

        default:
            break;
        }
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        // TODO Auto-generated method stub
        Log.d(TAG, "what:"+what);
        StopPlay();
        return false;
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        // TODO Auto-generated method stub
        StopPlay();
        mSucBtn.setVisibility(View.VISIBLE);
        Log.d(TAG, "onCompletion");
    }

    Runnable runnable = new Runnable() {

        final static int SAMPLE_RATE = 8000;

        public void run() {

            Log.d(TAG, "LoopBack started");

            mRunning = true;
            int bufferSize = AudioRecord
                    .getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
                            AudioFormat.ENCODING_PCM_16BIT);
            bufferSize = Math.max(bufferSize, AudioTrack.getMinBufferSize(
                    SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
                    AudioFormat.ENCODING_PCM_16BIT));

            AudioRecord audioRecord = new AudioRecord(
                    MediaRecorder.AudioSource.MIC, SAMPLE_RATE,
                    AudioFormat.CHANNEL_IN_MONO,
                    AudioFormat.ENCODING_PCM_16BIT, bufferSize);

            AudioTrack audioTrack = new AudioTrack(
                    AudioManager.STREAM_VOICE_CALL, SAMPLE_RATE,
                    AudioFormat.CHANNEL_OUT_MONO,
                    AudioFormat.ENCODING_PCM_16BIT, bufferSize,
                    AudioTrack.MODE_STREAM);

            audioTrack.setPlaybackRate(SAMPLE_RATE);

            audioRecord.startRecording();
            audioTrack.play();

            byte[] buffer = new byte[bufferSize];
            while (mRunning) {
                int readSize = audioRecord.read(buffer, 0, bufferSize);
                if (readSize > 0)
                    audioTrack.write(buffer, 0, readSize);
            }
            audioRecord.stop();
            audioRecord.release();
            audioTrack.stop();
            audioTrack.release();
        };
    };

    void startLoopBackThread() {
      if (!mRunning){
           new Thread(runnable).start();
       }
    }

    public void setAudio() {

        mAudioManager.setMode(AudioManager.MODE_NORMAL);

        float ratio = 0.4f;

        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
                (int) (ratio * mAudioManager
                        .getStreamMaxVolume(AudioManager.STREAM_MUSIC)), 0);
        mAudioManager
                .setStreamVolume(
                        AudioManager.STREAM_VOICE_CALL,
                        (int) (ratio * mAudioManager
                                .getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL)),
                        0);
        mAudioManager.setStreamVolume(AudioManager.STREAM_RING,
                (int) (ratio * mAudioManager
                        .getStreamMaxVolume(AudioManager.STREAM_RING)), 0);
        mAudioManager.setStreamVolume(AudioManager.STREAM_SYSTEM,
                (int) (ratio * mAudioManager
                        .getStreamMaxVolume(AudioManager.STREAM_SYSTEM)), 0);

    }

}
